package com.wanfajie.smsdistribute.db.repository.impl

import com.j256.ormlite.dao.Dao
import com.j256.ormlite.misc.TransactionManager
import com.j256.ormlite.stmt.ColumnArg
import com.j256.ormlite.stmt.QueryBuilder
import com.j256.ormlite.stmt.Where
import com.wanfajie.smsdistribute.MyApplication
import com.wanfajie.smsdistribute.db.bean.sms.SmsBean
import com.wanfajie.smsdistribute.db.bean.sms.SmsPartBean
import com.wanfajie.smsdistribute.db.helper.SmsDatabaseHelper
import com.wanfajie.smsdistribute.db.repository.SmsRecordRepository

object SmsRecordRepositoryImpl: SmsRecordRepository {

    private val recordDao: Dao<SmsBean, Int>
    private val partDao: Dao<SmsPartBean, *>
    private val helper = SmsDatabaseHelper(MyApplication.context)

    init {
        recordDao = helper.getDao(SmsBean::class.java)
        partDao = helper.getDao(SmsPartBean::class.java)
    }

    override fun query(filter: SmsRecordRepository.Filter, kw: String): List<SmsBean> {
        val builder = recordDao.queryBuilder()
        builder.orderBy(SmsBean.FIELD_TS, false).query()
        val where: Where<SmsBean, Int> by lazy { builder.where() }

        val smsFailureBuilder: QueryBuilder<SmsPartBean, *> by lazy {
            partDao.queryBuilder().apply {
                selectColumns(SmsPartBean.FIELD_ID)
                where().ne(SmsPartBean.FIELD_RESULT, SmsPartBean.RESULT_OK)
                        .and()
                        .eq(SmsPartBean.FIELD_ID, ColumnArg(SmsBean.TABLE_NAME, SmsBean.FIELD_ID))
                limit(1)
            }
        }

        var filterWhere: Where<SmsBean, Int>? = null

        when (filter) {
            SmsRecordRepository.Filter.ALL -> Unit
            SmsRecordRepository.Filter.SUCCESS -> {
                filterWhere = where.not().exists(smsFailureBuilder)
            }
            SmsRecordRepository.Filter.FAILURE -> {
                filterWhere = where.exists(smsFailureBuilder)
            }
        }

        if (kw.isNotEmpty()) {
            // XXX: 对kw转义
            if (filterWhere != null) {
                where.and(
                    filterWhere,
                    where.or(
                            where.like(SmsBean.FIELD_MESSAGE, "%$kw%"),
                            where.like(SmsBean.FIELD_SENDTO, "%$kw%")
                    )
                )
            } else {
                where.like(SmsBean.FIELD_MESSAGE, "%$kw%")
                        .or()
                        .like(SmsBean.FIELD_SENDTO, "%$kw%")
            }
        }

        return builder.query()
    }

    override fun remove(sms: SmsBean): Boolean {
        return recordDao.delete(sms) > 0
    }

    override fun resetSmsStatus(sms: SmsBean): Int {
        val connSource = helper.connectionSource
        return TransactionManager.callInTransaction(connSource) {
            val builder = partDao.deleteBuilder()
            builder.where()
                    .eq(SmsPartBean.FIELD_ID, sms.id)

            val updateBuilder = recordDao.updateBuilder()
            updateBuilder.updateColumnValue(SmsBean.FIELD_TS, System.currentTimeMillis())
                    .where()
                    .eq(SmsBean.FIELD_ID, sms.id)

            updateBuilder.update() +
            builder.delete()
        }
    }
}